﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace LunarSF.SHomeWorkshop.LMParser.MarkdownDOM
{
    public class Markdown元素
    {
        public Markdown元素(string markdownFilePath)
        {

        }

        protected 元素名称 _元素名称;

        public 元素名称 元素名称 { get { return _元素名称; } }

        protected 元素类别 _元素类别;

        public 元素类别 元素类别 { get { return _元素类别; } }
    }

    /// <summary>
    /// 大类别.
    /// </summary>
    public enum 元素类别
    {
        单行元素,
        连续多行元素,
        嵌套多行元素,
    }

    /// <summary>
    /// 具体元素类别.
    /// </summary>
    public enum 元素名称
    {
        普通文本,
        六级标题行,
        冒号注释行,
        分号注释行,
        无序列表行,
        有序列表行,
        代码块行,
        引用块行,
        图像链接行,
        文件链接行,
        锚链接行,
        树型文字表,
        二维文字表,
        自定义折叠区,
        文档元素,
    }

    public abstract class 单行元素 : Markdown元素
    {
        public 单行元素(string content, string markdownFilePath) : base(markdownFilePath)
        {
            this._元素类别 = 元素类别.单行元素;

            this._元素内容文本 = content;
        }

        protected string _元素内容文本;
        /// <summary>
        /// 只有单行元素才应有内容。多行元素的内容由子元素列表存储！
        /// 连续多行元素的内容（例如二维文字表）也由其子元素列表（中的单行元素）存储！
        /// </summary>
        public string 元素内容文本 { get { return _元素内容文本; } }
    }

    public abstract class 多行元素 : Markdown元素
    {
        public 多行元素(string markdownFilePath) : base(markdownFilePath)
        {
            _子元素列表 = new List<Markdown元素>();
        }

        private List<Markdown元素> _子元素列表;

        public List<Markdown元素> 子元素列表
        {
            get { return _子元素列表; }
        }
    }

    public abstract class 连续多行元素 : 多行元素
    {
        public 连续多行元素(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素类别 = 元素类别.连续多行元素;
        }
    }

    public abstract class 嵌套多行元素 : 多行元素
    {
        public 嵌套多行元素(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素类别 = 元素类别.嵌套多行元素;
        }
    }

    #region 以下为具体Markdown元素类

    public class 六级标题行 : 单行元素
    {
        public 六级标题行(string content, string markdownFilePath) : base(content, markdownFilePath)
        {
            this._元素名称 = 元素名称.六级标题行;
            this._元素类别 = 元素类别.单行元素;

            if (string.IsNullOrWhiteSpace(content) == false)
            {
                var 匹配规则 = MarkdownDOMParser.取匹配规则(元素名称.六级标题行) as 六级标题行匹配规则;
                if (匹配规则 != null && 匹配规则.表达式 != null)
                {
                    var match = 匹配规则.表达式.Match(content);
                    if (match.Success)
                    {
                        var trimChars = new char[] { ' ', '　', '\t' };
                        this._标题文本 = match.Value.Trim(trimChars).Replace('＃', '#');
                        this._标题层级 = this._标题文本.Length;
                        this._标题文本 = content.Substring(match.Length).Trim(trimChars);
                    }
                }
            }
        }

        private string _头文本;

        public string 头文本 { get { return _头文本; } }

        private string _标题文本;

        public string 标题文本 { get { return _标题文本; } }

        public int _标题层级;

        public int 标题层级 { get { return _标题层级; } }
    }

    /* 具体元素包括：
     * 六级标题
     * 伪标题
     * 水平线
     * 引用块
     * 代码块
     * 无序列表项
     * 有序列表项
     * 单行图像链接
     * 
     * 二维文字表
     * 树型文字表
     * 任务列表项
     * 试题（填空、选择【含判断】、材料分析）
     * 分号注释
     * 冒号注释
     * 锚
     * 文档标题
     * 页眉文本
     * 页脚文本
     * 自定义折叠区
     * 方块区域
     * 按倍数放大文本
     * Step标记
     * 连续标点标记（双句点、双句号、双叹号、双问号）
     * 
     * ** 并行标记要另行提前处理
     */

    public class 分号注释行 : 单行元素
    {
        public 分号注释行(string content, string markdownFilePath) : base(content, markdownFilePath)
        {
            this._元素名称 = 元素名称.分号注释行;
            this._元素类别 = 元素类别.单行元素;
        }
    }

    public class 冒号注释行 : 单行元素
    {
        public 冒号注释行(string content, string markdownFilePath) : base(content, markdownFilePath)
        {
            this._元素名称 = 元素名称.冒号注释行;
            this._元素类别 = 元素类别.单行元素;
        }
    }

    public class 代码块行 : 连续多行元素
    {
        public 代码块行(string markdownFilePath):base(markdownFilePath)
        {
            this._元素名称 = 元素名称.代码块行;
            this._元素类别 = 元素类别.连续多行元素;
        }
    }

    public class 树型文字表 : 连续多行元素
    {
        public 树型文字表(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素名称 = 元素名称.树型文字表;
            this._元素类别 = 元素类别.连续多行元素;
        }
    }

    public class 二维文字表 : 连续多行元素
    {
        public 二维文字表(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素名称 = 元素名称.二维文字表;
            this._元素类别 = 元素类别.连续多行元素;
        }
    }

    public class 自定义折叠区 : 嵌套多行元素
    {
        public 自定义折叠区(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素名称 = 元素名称.自定义折叠区;
            this._元素类别 = 元素类别.嵌套多行元素;
        }
    }

    public class 方块区域 : 嵌套多行元素
    {
        public 方块区域(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素名称 = 元素名称.文档元素;
            this._元素类别 = 元素类别.嵌套多行元素;
        }
    }

    public class 文档元素 : 嵌套多行元素
    {
        public 文档元素(string markdownFilePath) : base(markdownFilePath)
        {
            this._元素名称 = 元素名称.文档元素;
            this._元素类别 = 元素类别.嵌套多行元素;
        }
    }
    #endregion 以上为具体Markdown元素类。
}
